package com.imoresoft.agile.top;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.imoresoft.agile.entity.ResultCode;
import com.imoresoft.agile.exception.ProException;
import com.taobao.api.ApiException;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.TaobaoRequest;
import com.taobao.api.TaobaoResponse;

public class TopClient {

	final Logger logger = LoggerFactory.getLogger(this.getClass());

	private TaobaoClient taobaoClient = null;

	private int tryTimesWhenError = TopConstants.TAOBAO_API_CALL_MAX_TIMES;

	public TopClient() {
		this(false, TopConstants.APP_KEY, TopConstants.APP_SECRET);
	}

	public TopClient(boolean isRealEnv, String appkey, String appsecret) {
		String topUrl = TopConstants.API_SANDBOX_SERVICE_URL;
		if (isRealEnv) {
			topUrl = TopConstants.API_SERVICE_URL;
		}
		taobaoClient = new DefaultTaobaoClient(topUrl, appkey, appsecret);
	}

	public int getTryTimesWhenError() {
		return tryTimesWhenError;
	}

	public void setTryTimesWhenError(int tryTimesWhenError) {
		this.tryTimesWhenError = tryTimesWhenError;
	}

	public <T extends TaobaoResponse> T execute(TaobaoRequest<?> request,
			String nick) throws ProException {
		return execute(request, null, nick);
	}

	@SuppressWarnings("unchecked")
	public <T extends TaobaoResponse> T execute(TaobaoRequest request,
			String sessionId, String nick) throws ProException {
		logger.info(nick + "准备调用" + request.getApiMethodName());
		TaobaoResponse taobaoResponse = null;
		int tryTimes = 1;
		while (tryTimes <= tryTimesWhenError) {
			try {
				taobaoResponse = taobaoClient.execute(request, sessionId);
			} catch (ApiException e) {
				logger.warn(nick + "在第" + tryTimes + "次调用淘宝接口"
						+ request.getApiMethodName() + "出现ApiException.", e);
				if (++tryTimes > tryTimesWhenError) {
					String desc = nick + "调用Taobao Api已达到最大异常重试次数";
					logger.error(desc, e);
					throw new ProException(ResultCode.TOP_CLIENT_EXCEPTION,
							desc, e);
				}
				try {
					Thread
							.sleep(TopConstants.TAOBAO_API_CALL_INTERVAL_WHEN_ERROR);
				} catch (InterruptedException e1) {
				}
				continue;
			}
			if (taobaoResponse.isSuccess()) {
				logger.info(nick + "调用" + request.getApiMethodName()
						+ "接口成功返回.");
				break;
			} else {
				String desc = nick + "调用" + request.getApiMethodName()
						+ "接口时因平台/业务级问题而失败.";
				throw new ProException(ResultCode.TOP_SERVER_EXCEPTION, desc,
						taobaoResponse.getErrorCode(), taobaoResponse.getMsg(),
						taobaoResponse.getSubCode(), taobaoResponse.getSubMsg());
			}
		}
		return (T) taobaoResponse;
	}
}